package dipl.algorithm.math.primitive;

import dipl.algorithm.math.utility.FPMath;
import dipl.algorithm.math.utility.ApfloatUtils;
import org.apfloat.Apfloat;

/**
 * point in 3d euclidian or 2d projective space
 */
public class Point3d {

	//
	// CONSTRUCTOR METHODS
	//

	public Point3d() {
		x = ApfloatUtils._0;
		y = ApfloatUtils._0;
		z = ApfloatUtils._0;
	}

	public Point3d( Apfloat x, Apfloat y, Apfloat z ) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	public Point3d( Point3d other ) {
		x = other.z;
		y = other.y;
		z = other.z;
	}

	//
	// PUBLIC METHODS
	//

	/**
	 * Converts point from (x,y,w) to (x/w,y/w,1) if w != 0
	 * @param fpMath
	 */
	public void ToCartesian( FPMath fpMath ) {
		if( z.compareTo( Apfloat.ZERO ) == 0 ) return;
		x = fpMath.m.divide( x, z );
		y = fpMath.m.divide( y, z );
		z = ApfloatUtils._1;
	}

	/**
	 * Takes coordinates from given point
	 * @param other
	 */
	public void Set( Point3d other ) {
		x = other.x;
		y = other.y;
		z = other.z;
	}

	/**
	 * Takes given coordinates
	 * @param x
	 * @param y
	 * @param z
	 */
	public void Set( Apfloat x, Apfloat y, Apfloat z ) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	@Override
	public String toString() {
		return "(x:"+x.toString( true )+", y:"+y.toString( true )+", z:"+z.toString( true )+")";
	}

	//
	// MEMBERS
	//

	public Apfloat x;
	public Apfloat y;
	public Apfloat z;
}
